import tensorflow as tf
from tensorflow import keras

import numpy as np

print(tf.__version__)

# -- 下载 IMDB 数据集
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

print("Training entries: {}, labels: {}".format(len(train_data), len(train_labels)))

# --探索数据
print(train_data[0])
len(train_data[0]), len(train_data[1])

# --将整数转换回单词
# 一个映射单词到整数索引的词典
word_index = imdb.get_word_index()
# 保留第一个索引
word_index = {k: (v + 3) for k, v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2  # unknown
word_index["<UNUSED>"] = 3
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])


def decode_review(text):
    return ' '.join([reverse_word_index.get(i, '?') for i in text])


decode_review(train_data[0])

# --准备数据
# 影评——即整数数组必须在输入神经网络之前转换为张量(矩阵)。这种转换可以通过以下两种方式来完成：
# 1 将数组转换为表示单词出现与否的由 0 和 1 组成的向量，类似于 one-hot 编码
#   例如，序列[3, 5]将转换为一个 10,000 维的向量，该向量除了索引为 3 和 5 的位置是 1 以外，其他都为 0。
#   然后，将其作为网络的首层——一个可以处理浮点型向量数据的(稠密层)。不过，这种方法需要大量的内存，需要一个大小为 num_words * num_reviews 的矩阵。
# 2 或者，我们可以填充数组来保证输入数据具有相同的长度，然后创建一个大小为 max_length * num_reviews 的整型张量。
#   我们可以使用能够处理此形状数据的嵌入层作为网络中的第一层。
#
# pad_sequences 将train_data的所有数据都填充成相同的大小
train_data = keras.preprocessing.sequence.pad_sequences(train_data,
                                                        value=word_index["<PAD>"],
                                                        padding='post',
                                                        maxlen=256)
test_data = keras.preprocessing.sequence.pad_sequences(test_data,
                                                       value=word_index["<PAD>"],
                                                       padding='post',
                                                       maxlen=256)
